package cn.snow.iot.module.warning.rabbitmq;


import cn.snow.iot.module.warning.controller.admin.config.vo.WarningDetailVO;
import cn.snow.iot.module.warning.event.*;
import cn.snow.iot.module.warning.service.config.IWarningService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 启动后监听rabbit的告警通知队列，当收到新的告警信息后，解析消息并且做业务处理
 * @author chen_gang
 */
@Slf4j
@Component
public class WarningQueueHandler {

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@Autowired
	private IWarningService warningService;

	@Autowired
	private ApplicationEventPublisher eventPublisher;

	/**
	 * 监听告警通知队列，处理告警消息
	 * @param message
	 */
	@RabbitListener(queues = "iot.warning.result")
	public void warningHandler(JSONObject message) {
		try {
			log.info("warning <===> 接收告警消息：{}", message);
			distributionWarning(message);
		} catch (Exception e) {
            log.error("warning <===> 接收告警消息异常：{}", e);
        }
    }

	/**
	 * 接收到告警消息后，使用事件驱动机制分别进行以下处理： 1.保存告警记录 2.执行告警动作
	 * 查询此告警配置的动作列表，分别发布对应事件
	 * @param message
	 */
	private void distributionWarning(JSONObject message) {
		final String uuId = UUID.randomUUID().toString();
		//1.根据告警信息查询平台相关的告警配置和动作列表
		//从告警消息内容获取平台告警配置id
		Long warningId = message.getLong("warningId");
		//获取对应的告警配置信息和动作列表
		WarningDetailVO warningDetailVO = warningService.selectWarningById(warningId);
		//遍历动作列表，逐一进行事件发布
		warningDetailVO.getActionDOList().forEach(action -> {
			MessageWarningEvent event = new MessageWarningEvent(message, action.getRelatedParameter(), uuId, action.getId(),warningDetailVO);
			//发布事件
			eventPublisher.publishEvent(event);
			log.info("发布事件完成 {}", event);
		});

		//发布mysql持久化事件，进行告警信息留痕
		eventPublisher.publishEvent(new MysqlWarningEvent(message, uuId));
	}
}
